package 多线程; // 定义包名

import java.util.concurrent.ArrayBlockingQueue; // 导入ArrayBlockingQueue类
import java.util.concurrent.FutureTask; // 导入FutureTask类
import java.util.concurrent.ThreadPoolExecutor; // 导入ThreadPoolExecutor类
import java.util.concurrent.TimeUnit; // 导入TimeUnit类
import java.util.concurrent.atomic.AtomicInteger; // 导入AtomicInteger类
import java.lang.reflect.Field; // 导入Field类
import java.util.*; // 导入java.util包
import java.lang.Thread; // 导入Thread类

public class threadPoolExecutorTest { // 定义类，用于测试线程池执行器
    
    static class MyTask implements Runnable{ // 定义内部类MyTask，实现Runnable接口
        
        private final String name; // 任务名称
        private final long duration; // 任务持续时间

        public MyTask(String name){this(name, 0);} // 构造函数，调用另一个构造函数

        public MyTask(String name, long duration){ // 构造函数，初始化任务名称和持续时间
            this.name = name;
            this.duration = duration;
        }

        @Override
        public void run(){ // 重写run方法，定义任务执行逻辑
            try {
                System.out.println(Thread.currentThread().getName() + "...is...running..."); // 输出线程运行信息
                Thread.sleep(duration); // 线程休眠指定时间
            } catch (Exception e) { // 捕获异常
                e.printStackTrace(); // 打印异常堆栈
            }
        }

        @Override
        public String toString(){ // 重写toString方法，返回任务信息
            return "MyTask(" + name + ")";
        }
    }

    public static void main(String[] args) throws InterruptedException{ // 主方法，程序的入口
        AtomicInteger c = new AtomicInteger(1); // 创建一个原子整数，初始值为1
        ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(2); // 创建一个容量为2的阻塞队列

        // LinkedBlockingQueue<Runnable> linkedBlockingQueue = new LinkedBlockingQueue<>(); // 创建一个无界阻塞队列
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(2, 3, // 创建线程池，核心线程数为2，最大线程数为3
                                                                 0, TimeUnit.MILLISECONDS, // 线程空闲时间为0毫秒
                                                                 queue, // 使用ArrayBlockingQueue作为任务队列
                                                                 r -> new Thread(r, "MyThread" + c.getAndIncrement()), // 线程工厂，创建新线程
                                                                 new ThreadPoolExecutor.DiscardPolicy()); // 拒绝策略，丢弃任务
        
        showState(queue, threadPool); // 显示线程池状态
        threadPool.submit(new MyTask("1", 3600000)); // 提交任务1，持续时间为3600000毫秒
        showState(queue, threadPool); // 显示线程池状态
        threadPool.submit(new MyTask("2", 3600000)); // 提交任务2，持续时间为3600000毫秒
        showState(queue, threadPool); // 显示线程池状态
        threadPool.submit(new MyTask("3")); // 提交任务3
        showState(queue, threadPool); // 显示线程池状态
        threadPool.submit(new MyTask("4")); // 提交任务4
        showState(queue, threadPool); // 显示线程池状态
        threadPool.submit(new MyTask("5", 3600000)); // 提交任务5，持续时间为3600000毫秒
        showState(queue, threadPool); // 显示线程池状态
        threadPool.submit(new MyTask("6")); // 提交任务6
        showState(queue, threadPool); // 显示线程池状态
    }

    private static void showState(ArrayBlockingQueue<Runnable> queue, ThreadPoolExecutor threadPool){ // 方法用于显示线程池状态
        try {
            Thread.sleep(300); // 线程休眠300毫秒
        } catch (Exception e) { // 捕获异常
            e.printStackTrace(); // 打印异常堆栈
        } 
        List<Object> tasks = new ArrayList<>(); // 创建一个列表用于存储任务
        for(Runnable runnable : queue){ // 遍历队列中的任务
            try {
                Field callable = FutureTask.class.getDeclaredField("callable"); // 获取FutureTask的callable字段
                callable.setAccessible(true); // 设置字段可访问
                Object adaptor = callable.get(runnable); // 获取callable字段的值
                Class<?> clazz = Class.forName("java.util.concurrent.Executors$RunnableAdapter"); // 获取RunnableAdapter类
                Field task = clazz.getDeclaredField("task"); // 获取task字段
                task.setAccessible(true); // 设置字段可访问
                Object o = task.get(adaptor); // 获取task字段的值
                tasks.add(o); // 将任务添加到列表中
            } catch (Exception e) { // 捕获异常
                e.printStackTrace(); // 打印异常堆栈
            }
        }
        System.out.println("pool size: " + threadPool.getPoolSize() + "queue: " + tasks); // 输出线程池大小和任务队列
    }
}
